package com.xiyi.shouxin.dao.user;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.xiyi.shouxin.dao.BaseRepository;
import com.xiyi.shouxin.dao.JdbcPreparedStatement;
import com.xiyi.shouxin.entity.user.User;
import com.xiyi.shouxin.entity.user.mapper.UserMapper;
import com.xiyi.shouxin.exception.CommonException;
import com.xiyi.shouxin.exception.ErrorCode;

@Repository
public class UserRepository extends BaseRepository<User> {

    public UserRepository() {
        super();
        super.stat = new JdbcPreparedStatement<>(User.class);
    }

    public User findByOpenid(String openid) throws CommonException {
        if (!StringUtils.hasText(openid)) {
            throw new CommonException(ErrorCode.INVALIDPARAMTER);
        }
        StringBuilder sb = new StringBuilder("SELECT ");
        sb.append(stat.GetQueryColumns());
        sb.append(" FROM ");
        sb.append(stat.GetTableName());
        sb.append(" WHERE ");
        sb.append(stat.GetColumnName("openid"));
        sb.append(" = ? AND ");
        sb.append(stat.GetColumnName("deletedAt") + " IS NULL LIMIT 1");
        try {
            User user = template.queryForObject(sb.toString(), new Object[] { openid }, new UserMapper());
            return user;
        } catch (EmptyResultDataAccessException e) {

        }

        return null;
    }


    public User findByPhone(String phone) throws CommonException {
        if (!StringUtils.hasText(phone)) {
            throw new CommonException(ErrorCode.INVALIDPARAMTER);
        }
        StringBuilder sb = new StringBuilder("SELECT ");
        sb.append(stat.GetQueryColumns());
        sb.append(" FROM ");
        sb.append(stat.GetTableName());
        sb.append(" WHERE ");
        sb.append(stat.GetColumnName("phone"));
        sb.append(" = ? AND ");
        sb.append(stat.GetColumnName("deletedAt") + " IS NULL LIMIT 1");
        try {
            User user = template.queryForObject(sb.toString(), new Object[] { phone }, new UserMapper());
            return user;
        } catch (EmptyResultDataAccessException e) {
            // 没有找到对应用户，返回null
        }
        return null;
    }


    public User findByStudentId(String studentId) throws CommonException {
        if (!StringUtils.hasText(studentId)) {
            throw new CommonException(ErrorCode.INVALIDPARAMTER);
        }
        StringBuilder sb = new StringBuilder("SELECT ");
        sb.append(stat.GetQueryColumns());
        sb.append(" FROM ");
        sb.append(stat.GetTableName());
        sb.append(" WHERE ");
        sb.append(stat.GetColumnName("studentId"));
        sb.append(" = ? AND ");
        sb.append(stat.GetColumnName("deletedAt") + " IS NULL LIMIT 1");
        try {
            User user = template.queryForObject(sb.toString(), new Object[] { studentId }, new UserMapper());
            return user;
        } catch (EmptyResultDataAccessException e) {

        }

        return null;
    }

    public List<User> findByMultiConditionsByPage( Long adminId,String keyword, Date startTime, Date endTime, Sort sort, int page,
            int size)
            throws Exception {
        List<Object> args = new ArrayList<>();
        List<String> conditions = new ArrayList<>();
        if (StringUtils.hasText(keyword)) {
            String cond = stat.GetColumnName("deviceId") + " LIKE ? OR ";
            cond = cond + stat.GetColumnName("nickName") + " LIKE ? OR ";
            cond = cond + stat.GetColumnName("phone") + " LIKE ? ";
            conditions.add(cond);
            args.add("%" + keyword + "%");
            args.add("%" + keyword + "%");
            args.add("%" + keyword + "%");
        }
        if (adminId != null) {
            conditions.add(stat.GetColumnName("adminId") + " = ? ");
            args.add(adminId);
        }
        if (startTime != null) {
            conditions.add(stat.GetColumnName("createdAt") + " >= ? ");
            args.add(startTime);
        }
        if (endTime != null) {
            conditions.add(stat.GetColumnName("createdAt") + " <= ? ");
            args.add(endTime);
        }
        conditions.add(stat.GetColumnName("deletedAt") + " IS NULL ");
        return findByMultiConditionsByPage(conditions, args, sort, page, size, new UserMapper());
    }

    public int countByMultiConditions( Long adminId,String keyword, Date startTime, Date endTime) {
        List<Object> args = new ArrayList<>();
        List<String> conditions = new ArrayList<>();
        if (StringUtils.hasText(keyword)) {
            String cond = stat.GetColumnName("deviceId") + " LIKE ? OR ";
            cond = cond + stat.GetColumnName("nickName") + " LIKE ? OR ";
            cond = cond + stat.GetColumnName("phone") + " LIKE ? ";
            conditions.add(cond);
            args.add("%" + keyword + "%");
            args.add("%" + keyword + "%");
            args.add("%" + keyword + "%");
        }
        if (adminId != null) {
            conditions.add(stat.GetColumnName("adminId") + " = ? ");
            args.add(adminId);
        }
        if (startTime != null) {
            conditions.add(stat.GetColumnName("createdAt") + " >= ? ");
            args.add(startTime);
        }
        if (endTime != null) {
            conditions.add(stat.GetColumnName("createdAt") + " <= ? ");
            args.add(endTime);
        }
        conditions.add(stat.GetColumnName("deletedAt") + " IS NULL ");
        return countByMultiConditions(conditions, args);
    }

    public List<Long> selectIdsByAdminIdAndKeyword(Long adminId,String keyword) throws Exception {
        if (!StringUtils.hasText(keyword)&&adminId==null) {
            throw new CommonException(ErrorCode.INVALIDPARAMTER);
        }
        List<Object> args=new ArrayList<>();
        List<String> conditions = new ArrayList<>();
        StringBuilder sb = new StringBuilder("SELECT id FROM ");
        sb.append(stat.GetTableName());
        if (StringUtils.hasText(keyword)) {
            String cond = stat.GetColumnName("deviceId") + " LIKE ? OR ";
            cond = cond + stat.GetColumnName("nickName") + " LIKE ? OR ";
            cond = cond + stat.GetColumnName("phone") + " LIKE ? ";
            conditions.add(cond);
            args.add("%" + keyword + "%");
            args.add("%" + keyword + "%");
            args.add("%" + keyword + "%");
        }
        if (adminId != null) {
            conditions.add(stat.GetColumnName("adminId") + " = ? ");
            args.add(adminId);
        }
        if (!conditions.isEmpty()) {
            sb.append(" WHERE ");
            for (int i = 0; i < conditions.size(); i++) {
                String cond=conditions.get(i);
                cond="("+cond+")";
                conditions.set(i, cond);
            }
            sb.append(String.join(" AND ", conditions));
        }
        List<Long> ids = template.queryForList(sb.toString(), args.toArray(),Long.class);
        return ids;
    }

    public List<Long> selectIdsByAdminId(Long adminId) throws Exception {
        if (adminId == null) {
            throw new CommonException(ErrorCode.INVALIDPARAMTER);
        }
        StringBuilder sb = new StringBuilder("SELECT id FROM ");
        sb.append(stat.GetTableName());
        sb.append("WHERE ");
        sb.append(stat.GetColumnName("adminId"));
        sb.append(" = ? AND ");
        sb.append(stat.GetColumnName("deletedAt") + " IS NULL ");
        List<Long> ids = template.queryForList(sb.toString(), Long.class, adminId);
        return ids;
    }

    public Long countTotal() {
        StringBuilder sb = new StringBuilder("SELECT COUNT(1) FROM ");
        sb.append(stat.GetTableName());
        sb.append(" WHERE ");
        sb.append(stat.GetColumnName("deletedAt"));
        sb.append(" IS NULL ");
        try {
            Long total = template.queryForObject(sb.toString(), Long.class);
            return total;
        } catch (EmptyResultDataAccessException e) {

        }
        return 0L;
    }

    public User findByAdminId(Long adminId) throws Exception {
        if (adminId == null) return null;
        String sql = "SELECT `id`,`adminId`,`device_id`,`account`,`nickname`,`realname`,`avatar`,`sex`,`phone`,`province`,`city`,`area`,`token`,`openid`,`session_key`,`is_bind`,`is_answer`,`created_at`,`updated_at`,`deleted_at`,`student_id`,`feedback`" +
                     "FROM `user` WHERE `adminId` = ? AND `deleted_at` IS NULL LIMIT 1";
        try {
            return template.queryForObject(sql, new Object[] { adminId }, new com.xiyi.shouxin.entity.user.mapper.UserMapper());
        } catch (Exception e) {
            return null;
        }
    }


}
